• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp15
r3wp107
total:122

results window for this page: [start: 101 end: 122]

world-name: r3wp

Group: Parse ... Discussion of PARSE dialect [web-public]
Ashley:
2-Dec-2011
load-csv fails to deal with these 3 simple (and for me, common) cases:

1,"a
b"
2,"a""b"
3,

>> load-csv %test.csv
== [["1" "a"] [{b"}] ["2" "a" "b"] ["3"]]

I've reverted to an in situ brute force approach:

c: make function! [data /local s] [
		all [find data "|" exit]
		s: false
		repeat i length? trim data [
			switch pick data i [
				#"^""	[s: complement s]
				#","	[all [not s poke data i #"|"]]
				#"^/"	[all [s poke data i #" "]]
			]
		]
		remove-each char data [char = #"^""]

  all [#"|" = last data insert tail data #"|"]	; only required if we're 
  going to parse the data
		parse/all data "|^/"
]

which has 4 minor limitations:

1) the data can't contain the delimter you're going to use ("|" in 
my case)

2) it replaces quoted returns with another character (" " in my code)

3) it removes all quote (") characters (to allow SQLite .import and 
parse/all to function correctly)
4) Individual values are not trimmed (e.g.c "a ,b" -> ["a " "b"])


If you can live with these limitations then the big benefit is that 
you can omit the last two lines and have a string that is import 
friendly for SQLite (or SQL Server) ... this is especially important 
when dealing with large (100MB+) CSV files! ;)
BrianH:
20-Dec-2011
Be careful, if you don't quote string values then the character set 
of your values can't include cr, lf or your delimiter. It requires 
so many changes that it would be more efficient to add new formatter 
functions to the associated FUNCT/with object, then duplicate the 
code in TO-CSV that calls the formatter. Like this:

to-csv: funct/with [
	"Convert a block of values to a CSV-formatted line in a string."
	data [block!] "Block of values"

 /with "Specify field delimiter (preferably char, or length of 1)"
	delimiter [char! string! binary!] {Default ","}
	; Empty delimiter, " or CR or LF may lead to corrupt data
	/no-quote "Don't quote values (limits the characters supported)"
] [
	output: make block! 2 * length? data
	delimiter: either with [to-string delimiter] [","]
	either no-quote [
		unless empty? data [append output format-field-nq first+ data]

  foreach x data [append append output delimiter format-field-nq :x]
	] [
		unless empty? data [append output format-field first+ data]
		foreach x data [append append output delimiter format-field :x]
	]
	to-string output
] [
	format-field: func [x [any-type!] /local qr] [

  ; Parse rule to put double-quotes around a string, escaping any inside

  qr: [return [insert {"} any [change {"} {""} | skip] insert {"}]]
		case [
			none? :x [""]
			any-string? :x [parse copy x qr]
			:x = #"^(22)" [{""""}]
			char? :x [ajoin [{"} x {"}]]
			money? :x [find/tail form x "$"]
			scalar? :x [form x]
			date? :x [to-iso-date x]

   any [any-word? :x binary? :x any-path? :x] [parse to-string :x qr]
			'else [cause-error 'script 'expect-set reduce [

    [any-string! any-word! any-path! binary! scalar! date!] type? :x
			]]
		]
	]
	format-field-nq: func [x [any-type!]] [
		case [
			none? :x [""]
			any-string? :x [x]
			money? :x [find/tail form x "$"]
			scalar? :x [form x]
			date? :x [to-iso-date x]
			any [any-word? :x binary? :x any-path? :x] [to-string :x]
			'else [cause-error 'script 'expect-set reduce [

    [any-string! any-word! any-path! binary! scalar! date!] type? :x
			]]
		]
	]
]


If you want to add error checking to make sure the data won't be 
corrupted, you'll have to pass in the delimiter to format-field-nq 
and trigger an error if it, cr or lf are found in the field data.
Group: !REBOL2 Releases ... Discuss 2.x releases [web-public]
BrianH:
31-Dec-2010
Some of what is coming in 2.7.8:

- Bug fixes and enhancements to improve Cheyenne, and other apps 
that have to do similar stuff.

- Some native fixes for non-Windows platforms, particularly Linux.

- Environment variable stuff: GET-ENV expansion on Windows, SET-ENV, 
LIST-ENV

- Function fixes: RUN enabled, LIST-REG/values, possibly TO-LOCAL-FILE

- R2/Forward: FUNCT/extern, LAST?, COLLECT-WORDS, EXTRACT fixes, 
ASCII? fixes, LATIN1? fixes, INVALID-UTF?, CD, LS, MORE, PWD, RM

- (Still pending) Natives: ASSERT, APPLY, RESOLVE, FOREACH set-word 
support
Group: Profiling ... Rebol code optimisation and algorithm comparisons. [web-public]
Gregg:
19-May-2010
Terry, I think INTERSECT is fine the way it is, and it's easy to 
wrap if you want.

    fold: func [
        series [series!]
        fn     [any-function!]
        /local value
    ][
        value: pick series 1
        foreach item next series [value: fn value item]
    ]

    intersect-all: func [
        series [block!] "A block of series values to intersect"
    ][
        fold series :intersect
    ]
Group: !REBOL3 GUI ... [web-public]
Cyphre:
14-Jan-2011
BTW what was the difference if you had:
faced: [area-color: red] ?


In the end the 'area-color was local to each style as well in face/facets. 
In Rebol you cannnot have mixed 'shared' and 'local' values of direct 
type in one object together.
Cyphre:
14-Jan-2011
From our expereinece with R3GUI styles, properties that user should 
easily access (like colors etc.) are meant to be usually local to 
each face inastance. That's for what FACES are good enough. If style 
creator think he could 'save' some memory by using shared values 
among faces of the style then he(she) can use the INTERN 'shared 
context' as storage.
Pekr:
14-Feb-2011
Rebolek - I hope you know what you are talking about :-) FACED was 
usefull - it was local instance copy of the value, not the shared 
one. FACETS then kept the values shared. RMA changed the design, 
so that FACETS are now instance local, which of course might lead 
to the increased memory consumption (that would have to be proven 
though). RMA introduced INTERN slot for holding instance local values, 
but from what I saw, that is not used that much yet ...
Group: !REBOL3 ... [web-public]
Oldes:
3-Aug-2010
For unused /local values. For unused refinements I think they must 
be #[none] to be able do code like:
f: func[/switch][ if switch [ true ] ]
Ladislav:
14-Nov-2010
This one is a poll question everyone should not have trouble to answer. 
In R2, the USE function initialized the local values to #[unset!] 
for better user protection. In R3 (implementation quirk) the local 
USE variables are initialized to #[none!]. Which alternative do you 
prefer?
Henrik:
14-Nov-2010
I think it should be the same, as if you were to use those values 
local to a function. Aren't they set to #[none] there too?
Anton:
14-Nov-2010
Good argument, Henrik.

Ladislav, you wrote "the USE function initialized the local values 
to #[unset!] for better user protection."

Better protection than what? Or what is the protection? (Or do you 
just mean USE creating locals is the protection?)
Ladislav:
14-Nov-2010
Sorry, improving the formulation:


In R2, the USE function initialized the local values to #[unset!] 
for better user protection against uninitialized variables (variables 
not initialized by the user).
BrianH:
25-May-2011
Jerry, the /local refinement is just another function option. If 
you provide that option when you call that function, you can provide 
initial values for the "local variables". In the case of sys/load-module, 
the security and control flow of that function depends on the local 
variables being initialized with the none value, so we want to avoid 
the /local option being used when the function is called. When a 
function refinement is not used its value is none, so if you want 
to ensure that it is none and trigger an error if it isn't, ASSERT/type 
[option none!] is the most efficient way to do this in R3.
Maxim:
26-May-2011
Geomol, you can use any other refinement, why use /local and allow 
a huge gap in security wrt intent of a local varable.  

I'd actually replace the /local handling of the function dialect 
and allow you to specify default values right in the function block.

f: func [a b /local i: 2 blk: [ ] ] [...]


The idea of /local is that its a protected, internal, set of words... 
most people don't even realize that it is just another normal refinement.
BrianH:
27-May-2011
That last trick would be difficult to do safely though, at least 
as FUNCT is used in the mezzanine generation process. Mezzanines 
are generated with FUNCT but saved with MOLD into the form where 
they will be loaded at runtime. This means that FUNCT can't generate 
code that has inline function or datatype values in it, since they 
won't mold properly. Unless you inline the references to ASSERT and 
NONE!, those words couldn't be used as function parameters or local 
variables in the generated functions. Tradeoffs, I guess.
BrianH:
28-May-2011
It's really not any more of a problem for /local than it is for any 
other function option or argument, since the real problem is that 
the techniques for code injection have been revealed. Fortunately, 
so have the methods for avoiding or counteracting it: APPLY, type 
checking, get-words, or wrapping expressions in parens or putting 
them at the end of blocks to make sure that they can't get access 
to modifiable values later on in the block.
Group: Core ... Discuss core issues [web-public]
Maxim:
12-May-2011
just remember that in R3, the /local refinement might be given special 
status in a future release. this was mainly to prevent you from supplying 
default values to locals which can be a pretty big security hole 
right now.
Geomol:
18-Aug-2011
Gregg, about your questions.


1) Has this behavior ever been behind a bug in any of your REBOL 
code? If so, what was the context and what was the impact (e.g., 
how did you work around it)?


I guess, you mean series inside functions. I'm not for everything 
should do a copy, as Gabriele imply. The problem with series in functions 
is only a problem, because functions in REBOL isn't functions in 
the traditional understanding. They are semi-closures. If they were 
functions, the local values would just be on the stack. Because the 
locals live on, this was a problem for me years ago. First I solved 
it by putting COPY in series definitions, then I in many cases changed 
to just do a CLEAR, like in:

local-block: clear []


Now with the discovered behaviour regarding objects, I find the binding 
rules so complicated, that I would forget, how it works in two weeks. 
I will remember, that I have to be very careful, when making objects 
inside functions, especially if it's recursive functions. The consequence 
for me is, that I will probably put COPY/DEEP in, when making objects. 
As I won't start new big projects in REBOL, I will probably not do 
this a lot in practice.
Endo:
14-Sep-2011
and it's more useful than the other way I think. Once I wrote a function 
to test if two object is similar. It looks a bit silly but works 
for me. Can be extended to test values also:

similar?: func [
    {Returns true if both object has same words in same types.}
    o [object!] p [object!] /local test
][

    test: [if not equal? type? get in o word type? get in p word [return 
    false]]
    foreach word sort first o test
    foreach word sort first p test
    true
]
Group: !REBOL3 Proposals ... For discussion of feature proposals [web-public]
BrianH:
3-Nov-2010
Everything said about the concurrency model so far indicates that 
it will not be the fork/exec model. Instead it will be the "create 
a new user context from scratch and populate its task-local values 
from the shared stuff" model.
BrianH:
9-Nov-2010
you have no recourse

 is a polite way of saying "you are out of luck". At least regular 
 programmers would be out of luck there - I'm sure someone like Ladislav 
 could come up with an arcane workaround, or you could give up on 
 RETURN and EXIT and use another escape function instead, like THROW. 
 But I assume that you know what I meant by "recourse", and want the 
 point explained.


Pardon me, that question needs some background info. The return models 
are being used to deal with a basic problem of functions catching 
RETURN and EXIT when you don't want them to. This is the case with 
many mezzanine control functions which take and execute a block of 
code. We have been putting requests for new mezzanine control functions 
on hold for quite a while because they can't currently be made to 
pass through RETURN and EXIT, but USE and COLLECT got through before 
we started that, and the restriction is lifted now.


Let's use USE to illustrate, ignoring for the moment that USE *can* 
be rewritten so it doesn't use an inner function.

use: func [
    "Defines words local to a block."
    vars [block! word!] "Local word(s) to the block"
    body [block!] "Block to evaluate"
][
    apply make closure! reduce [to block! vars copy/deep body] []
]


USE uses an inner function to create a binding for its words (the 
closure!). For the dynamic return we have now, the inner function 
catches returns from the body, but even if it didn't the USE function 
itself would catch those returns as well.


One proposal to solve this would be to switch to definitional return, 
which means that RETURN and EXIT would be redefined in the code block 
of a function to return directly to that function, not any intermediate 
function in the call chain. This would solve returns being caught 
by the USE function itself, because the body of code that contains 
the 'return or 'exit words is not physically in the code of the USE 
function, it is only referenced by word. However, that block of code 
is used by the inner function as its code block, so the inner function 
would redefine those words and catch the returns.


If your function uses inner functions like USE does, and can't be 
rewritten to not use them, and you are using definitional return 
without the option to turn it off, then the inner function will localize 
RETURN and EXIT every time.


As a caveat, I wrote that phrase before I came up with the workaround 
in the next section of using direct references to the RETURN and 
EXIT function values instead of referring to them by name, which 
avoids the rebinding issues because no words are involved. See the 
code in http://curecode.org/rebol3/ticket.rsp?id=637to see what 
that workaround makes your code look like.
Maxim:
31-Jan-2011
;-----------------
	;-     swap-values()
	;

 ; given two words, it will swap the values these words reference 
 or contain.
	;-----------------
	swap-values: func [
		'a 'b 
		/local c
	][c: get a set a get b set b  c]


>> a: 5
>> b: 1
>> if a > b [swap-values a b]
>> a
== 1
>> b
== 5


I've been using this to make sure inputs are properly ordered or 
ranges normalized when it matters further down in the code.
101 / 1221[2]